﻿///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////

#include "MainForm.h"
#include "resource.h"
#include <boost/asio.hpp>
#include <wx/msw/dib.h>

wxImage LoadBitmapResourceAsImage(UINT nIDResource) {
	HBITMAP hBitmap = ::LoadBitmap(::GetModuleHandleW(nullptr), MAKEINTRESOURCE(nIDResource));
	if (!hBitmap) {
		return {};
	}
	wxDIB dib(hBitmap);
	::DeleteObject(hBitmap);
	auto img = dib.ConvertToImage();
	if (img.IsOk()) {
		return img;
	}
	return {};
}

///////////////////////////////////////////////////////////////////////////
MainForm::MainForm(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
{
	this->SetSizeHints(wxSize(800, 494), wxSize(-1, 494));

	wxBoxSizer* m_szrRoot;
	m_szrRoot = new wxBoxSizer(wxHORIZONTAL);

	m_pnlLeft = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxTAB_TRAVERSAL);
	m_pnlLeft->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
	m_pnlLeft->SetMaxSize(wxSize(230, -1));

	wxBoxSizer* m_szrLeft;
	m_szrLeft = new wxBoxSizer(wxVERTICAL);

	wxArrayString mSelSerialPortsChoices;
	mSelSerialPorts = new wxChoice(m_pnlLeft, wxID_ANY, wxDefaultPosition, wxDefaultSize, mSelSerialPortsChoices, 0);
	mSelSerialPorts->SetSelection(0);
	m_szrLeft->Add(mSelSerialPorts, 0, wxALL | wxEXPAND, 5);

	wxBoxSizer* bSizer5;
	bSizer5 = new wxBoxSizer(wxHORIZONTAL);


	bSizer5->Add(5, 0, 0, wxEXPAND, 0);

	m_staticText1 = new wxStaticText(m_pnlLeft, wxID_ANY, _("波特率："), wxDefaultPosition, wxSize(60, -1), 0);
	m_staticText1->Wrap(-1);
	bSizer5->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL, 0);

	m_spinBaudRateConfig = new wxSpinCtrl(m_pnlLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1000000, 115200);
	bSizer5->Add(m_spinBaudRateConfig, 1, wxALL | wxEXPAND, 0);


	bSizer5->Add(5, 0, 0, wxEXPAND, 0);

	m_btnOpenSerialPort = new wxButton(m_pnlLeft, wxID_ANY, _("打开"), wxDefaultPosition, wxSize(60, -1), 0);
	bSizer5->Add(m_btnOpenSerialPort, 0, wxALL, 0);


	bSizer5->Add(5, 0, 0, wxEXPAND, 0);


	m_szrLeft->Add(bSizer5, 0, wxEXPAND, 5);

	m_pnlDeviceConfig = new wxPanel(m_pnlLeft, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
	m_pnlDeviceConfig->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));

	wxBoxSizer* bSizer51;
	bSizer51 = new wxBoxSizer(wxVERTICAL);


	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer7;
	bSizer7 = new wxBoxSizer(wxHORIZONTAL);


	bSizer7->Add(5, 0, 0, 0, 5);

	m_modeSwtich = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	bSizer7->Add(m_modeSwtich, 0, wxALL, 5);
	bSizer51->Add(bSizer7, 0, wxEXPAND, 5);
	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer8;
	bSizer8 = new wxBoxSizer(wxHORIZONTAL);


	bSizer8->Add(5, 0, 0, wxEXPAND, 5);

	m_modeStepless = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, 0);
	bSizer8->Add(m_modeStepless, 0, wxALL, 5);

	m_slidrSetplessDiming = new wxSlider(m_pnlDeviceConfig, wxID_ANY, 50, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_BOTH | wxSL_HORIZONTAL | wxSL_SELRANGE | wxSL_VALUE_LABEL);
	bSizer8->Add(m_slidrSetplessDiming, 1, wxALL | wxEXPAND, 0);

	m_staticText8 = new wxStaticText(m_pnlDeviceConfig, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0);
	m_staticText8->Wrap(-1);
	bSizer8->Add(m_staticText8, 0, wxALL, 5);


	bSizer51->Add(bSizer8, 0, wxEXPAND, 5);


	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer9;
	bSizer9 = new wxBoxSizer(wxHORIZONTAL);


	bSizer9->Add(5, 0, 0, wxEXPAND, 5);

	m_modeSawtooth = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, 0);
	bSizer9->Add(m_modeSawtooth, 0, wxALL, 5);

	m_slidrSawInterval = new wxSlider(m_pnlDeviceConfig, wxID_ANY, 3000, 1000, 5000, wxDefaultPosition, wxDefaultSize, wxSL_BOTH | wxSL_HORIZONTAL | wxSL_SELRANGE | wxSL_VALUE_LABEL);
	bSizer9->Add(m_slidrSawInterval, 1, wxALL, 0);

	m_staticText9 = new wxStaticText(m_pnlDeviceConfig, wxID_ANY, _("毫秒"), wxDefaultPosition, wxDefaultSize, 0);
	m_staticText9->Wrap(-1);
	bSizer9->Add(m_staticText9, 0, wxALL, 5);


	bSizer51->Add(bSizer9, 0, wxEXPAND, 5);


	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer10;
	bSizer10 = new wxBoxSizer(wxHORIZONTAL);


	bSizer10->Add(5, 0, 0, wxEXPAND, 5);

	m_modeTriangle = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, 0);
	bSizer10->Add(m_modeTriangle, 0, wxALL, 5);

	m_slidrTrianInterval = new wxSlider(m_pnlDeviceConfig, wxID_ANY, 3000, 1000, 5000, wxDefaultPosition, wxDefaultSize, wxSL_BOTH | wxSL_HORIZONTAL | wxSL_SELRANGE | wxSL_VALUE_LABEL);
	bSizer10->Add(m_slidrTrianInterval, 1, wxALL, 0);

	m_staticText10 = new wxStaticText(m_pnlDeviceConfig, wxID_ANY, _("毫秒"), wxDefaultPosition, wxDefaultSize, 0);
	m_staticText10->Wrap(-1);
	bSizer10->Add(m_staticText10, 0, wxALL, 5);


	bSizer51->Add(bSizer10, 0, wxEXPAND, 5);


	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer11;
	bSizer11 = new wxBoxSizer(wxHORIZONTAL);


	bSizer11->Add(5, 0, 0, wxEXPAND, 5);

	m_modeSinWave = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, 0);
	bSizer11->Add(m_modeSinWave, 0, wxALL, 5);

	m_slidrSinInterval = new wxSlider(m_pnlDeviceConfig, wxID_ANY, 3000, 1000, 5000, wxDefaultPosition, wxDefaultSize, wxSL_BOTH | wxSL_HORIZONTAL | wxSL_SELRANGE | wxSL_VALUE_LABEL);
	bSizer11->Add(m_slidrSinInterval, 1, wxALL, 0);

	m_staticText11 = new wxStaticText(m_pnlDeviceConfig, wxID_ANY, _("毫秒"), wxDefaultPosition, wxDefaultSize, 0);
	m_staticText11->Wrap(-1);
	bSizer11->Add(m_staticText11, 0, wxALL, 5);


	bSizer51->Add(bSizer11, 0, wxEXPAND, 5);


	bSizer51->Add(0, 5, 0, wxEXPAND, 5);

	wxBoxSizer* bSizer12;
	bSizer12 = new wxBoxSizer(wxHORIZONTAL);


	bSizer12->Add(5, 0, 0, wxEXPAND, 5);

	m_modeAudioWave = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("    "), wxDefaultPosition, wxDefaultSize, 0);
	bSizer12->Add(m_modeAudioWave, 0, wxALIGN_CENTER|wxALL, 5);

	auto img = LoadBitmapResourceAsImage(IDB_BITMAP1);
	auto m_bitmap2 = new wxStaticBitmap( m_pnlDeviceConfig, wxID_ANY, wxBitmap(img), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer12->Add( m_bitmap2, 1, wxALL, 5 );
	bSizer12->Add( 15, 0, 0, wxEXPAND, 5 );

	bSizer51->Add(bSizer12, 0, wxEXPAND, 5);


	bSizer51->Add(0, 0, 1, wxEXPAND, 5);


	wxBoxSizer* bSizer15 = new wxBoxSizer( wxHORIZONTAL );

	auto m_panel7 = new wxPanel( m_pnlDeviceConfig, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	bSizer15->Add( m_panel7, 1, wxEXPAND | wxALL, 5 );

	m_lblModeStatus = new wxStaticText( m_pnlDeviceConfig, wxID_ANY, _(""), wxDefaultPosition, wxSize(160,-1 ), wxALIGN_CENTER_HORIZONTAL );
	m_lblModeStatus->Wrap( -1 );
	m_lblModeStatus->SetFont( wxFont( 16, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );

	bSizer15->Add( m_lblModeStatus, 1, 0, 5 );

	auto m_panel8 = new wxPanel( m_pnlDeviceConfig, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	bSizer15->Add( m_panel8, 1, wxEXPAND | wxALL, 5 );
	bSizer51->Add( bSizer15, 0, wxEXPAND, 5 );


	bSizer51->Add(0, 0, 1, wxEXPAND, 5);


	m_pnlDeviceConfig->SetSizer(bSizer51);
	m_pnlDeviceConfig->Layout();
	bSizer51->Fit(m_pnlDeviceConfig);
	m_szrLeft->Add(m_pnlDeviceConfig, 1, wxEXPAND | wxALL, 0);

	m_switchON = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("ON"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	bSizer7->Add(m_switchON, 0, wxALL, 5);
	bSizer7->Add(20, 0, 0, wxEXPAND, 5);
	m_switchOFF = new wxRadioButton(m_pnlDeviceConfig, wxID_ANY, _("OFF"), wxDefaultPosition, wxDefaultSize, 0);
	bSizer7->Add(m_switchOFF, 0, wxALL, 5);

	m_szrLeft->Add(0, 5, 0, wxEXPAND, 0);


	m_pnlLeft->SetSizer(m_szrLeft);
	m_pnlLeft->Layout();
	m_szrLeft->Fit(m_pnlLeft);
	m_szrRoot->Add(m_pnlLeft, 1, wxEXPAND | wxALL, 0);

	m_pnlRight = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
	m_pnlRight->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));

	wxBoxSizer* bSizer6;
	bSizer6 = new wxBoxSizer(wxVERTICAL);

	m_pnlShowWave = new WaveformPanel(m_pnlRight);
	m_pnlShowWave->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));

	bSizer6->Add(m_pnlShowWave, 1, wxEXPAND | wxALL, 5);

	m_pnlQrCode = new wxPanel(m_pnlRight, wxID_ANY, wxDefaultPosition, wxSize(-1, 200), wxTAB_TRAVERSAL);
	m_pnlQrCode->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));

	wxBoxSizer* bSizer14;
	bSizer14 = new wxBoxSizer(wxHORIZONTAL);


	bSizer14->Add(0, 0, 1, wxEXPAND, 5);

	auto imgBilibili = LoadBitmapResourceAsImage(IDB_BITMAP2);
	imgBilibili.Rescale(164, 164, wxIMAGE_QUALITY_HIGH);
	m_bmpBiliBili = new wxStaticBitmap(m_pnlQrCode, wxID_ANY, wxBitmap(imgBilibili), wxDefaultPosition, wxSize(160, 160), 0);
	bSizer14->Add(m_bmpBiliBili, 0, wxALIGN_CENTER | wxALL, 5);


	bSizer14->Add(0, 0, 1, wxEXPAND, 5);


	m_pnlQrCode->SetSizer(bSizer14);
	m_pnlQrCode->Layout();
	bSizer6->Add(m_pnlQrCode, 0, wxEXPAND | wxALL, 0);


	m_pnlRight->SetSizer(bSizer6);
	m_pnlRight->Layout();
	bSizer6->Fit(m_pnlRight);
	m_szrRoot->Add(m_pnlRight, 1, wxEXPAND | wxALL, 0);


	this->SetSizer(m_szrRoot);
	this->Layout();

	this->Centre(wxBOTH);

	// Connect Events
	m_btnOpenSerialPort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainForm::OnClickSerialPortOpenOrClose), NULL, this);
	m_modeSwtich->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4Switch), NULL, this);
	m_switchON->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnSwitchLedON), NULL, this);
	m_switchOFF->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnSwitchLedOFF), NULL, this);
	m_modeStepless->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4Stepless), NULL, this);
	m_modeSawtooth->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4Sawtooth), NULL, this);
	m_slidrSawInterval->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(MainForm::OnSawIntervalChanging), NULL, this);
	m_modeTriangle->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4Triangle), NULL, this);
	m_slidrTrianInterval->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(MainForm::OnTriangleIntervalChanging), NULL, this);
	m_modeSinWave->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4SinWave), NULL, this);
	m_slidrSinInterval->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(MainForm::OnSinIntervalChanging), NULL, this);
	m_modeAudioWave->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(MainForm::OnModeSelect4AudioWave), NULL, this);
	m_slidrSetplessDiming->Bind(wxEVT_SCROLL_THUMBTRACK, &MainForm::OnSteplessChanging, this);
	m_slidrSetplessDiming->Bind(wxEVT_SLIDER, &MainForm::OnSteplessChanging, this);

	InitWorkMode();
}

MainForm::~MainForm()
{
	util::audio::StopAudioRecording();
	if (targetDevice) {
		targetDevice->Disconnect();
		targetDevice.reset();
	}
}

void MainForm::WaveformPostNewData(double x, double y, int tag) {
	if (m_pnlShowWave) {
		m_pnlShowWave->AsyncPushData(tag, x, y);
	}
}

void MainForm::OnClickSerialPortOpenOrClose(wxCommandEvent& event) {
	event.Skip();

	auto maskPortSelection = [this](bool enable = false) {
		if (enable) {
			m_btnOpenSerialPort->SetLabelText(L"打开");
			m_pnlDeviceConfig->Enable(false);
		}
		else {
			m_btnOpenSerialPort->SetLabelText(L"关闭");
			m_pnlDeviceConfig->Enable(true);
		}
		m_spinBaudRateConfig->Enable(enable);
		mSelSerialPorts->Enable(enable);
	};

	if (targetDevice) {
		if (curWorkMode != WorkMode::Disable) {
			LeaveWorkMode(curWorkMode);
			curWorkMode = WorkMode::Disable;
		}
		targetDevice->Disconnect();
		targetDevice.reset();
		maskPortSelection(true);
		return;
	}

	auto bdrate = m_spinBaudRateConfig->GetValue();
	if (bdrate < 9600) {
		return;
	}

	auto idx = mSelSerialPorts->GetSelection();
	if (idx == wxNOT_FOUND || idx >= curComPorts.size()) {
		return;
	}

	const auto& dev = curComPorts[idx];
	targetDevice = std::make_unique<DeviceModel>(this, dev.friendlyName, dev.comPath);
	if (!targetDevice->Connect(bdrate)) {
		auto dialog = new wxMessageDialog(
			this, 
			wxString::Format(L"串口COM%d打开失败，可能已经被占用", dev.comPortNum),
			wxT("Error"), 
			wxOK | wxICON_ERROR
		);
		dialog->ShowModal();
		dialog->Destroy();
		targetDevice.reset();
		return;
	}
	maskPortSelection(false);
	ChangeWorkMode(WorkMode::Switch);
}

void MainForm::OnModeSelect4Switch(wxCommandEvent& event) {
	event.Skip(); 
	ChangeWorkMode(WorkMode::Switch);
}

void MainForm::OnModeSelect4Stepless(wxCommandEvent& event) {
	event.Skip();
	ChangeWorkMode(WorkMode::Stepless);
}

void MainForm::OnModeSelect4Sawtooth(wxCommandEvent& event) {
	event.Skip();
	ChangeWorkMode(WorkMode::Sawtooth);
}

void MainForm::OnModeSelect4Triangle(wxCommandEvent& event) {
	event.Skip();
	ChangeWorkMode(WorkMode::Triangle);
}

void MainForm::OnModeSelect4SinWave(wxCommandEvent& event) {
	event.Skip();
	ChangeWorkMode(WorkMode::SinWave);
}

void MainForm::OnModeSelect4AudioWave(wxCommandEvent& event) {
	event.Skip();
	ChangeWorkMode(WorkMode::AudioWave);
}

void MainForm::OnSteplessChanging(wxCommandEvent& event) {
	event.Skip();
	if (targetDevice) {
		targetDevice->LedSetFixedLightness(m_slidrSetplessDiming->GetValue());
	}
}

void MainForm::OnSawIntervalChanging(wxScrollEvent& event) {
	event.Skip();
	if (targetDevice) {
		targetDevice->LedSetSawtoothWave(m_slidrSawInterval->GetValue());
	}
}

void MainForm::OnTriangleIntervalChanging(wxScrollEvent& event) {
	event.Skip();
	if (targetDevice) {
		targetDevice->LedSetTriangleWave(m_slidrTrianInterval->GetValue());
	}
}

void MainForm::OnSinIntervalChanging(wxScrollEvent& event) {
	event.Skip();
	if (targetDevice) {
		targetDevice->LedSetSinWave(m_slidrSinInterval->GetValue());
	}
}

void MainForm::OnSwitchLedON(wxCommandEvent& event) {
	event.Skip();
	targetDevice->LedSetFixedLightness(100.0);
}

void MainForm::OnSwitchLedOFF(wxCommandEvent& event) {
	event.Skip();
	targetDevice->LedSetFixedLightness(0.0);
}

void MainForm::InitWorkMode() {
	EnableWorkModeUserInterface(WorkMode::Switch, false);
	EnableWorkModeUserInterface(WorkMode::Stepless, false);
	EnableWorkModeUserInterface(WorkMode::Sawtooth, false);
	EnableWorkModeUserInterface(WorkMode::Triangle, false);
	EnableWorkModeUserInterface(WorkMode::SinWave, false);
	EnableWorkModeUserInterface(WorkMode::AudioWave, false);
	m_pnlDeviceConfig->Enable(false);

	curComPorts = util::ser::EnumCurrentSerialPorts();
	if (curComPorts.empty()) {
		m_btnOpenSerialPort->Enable(false);
		m_spinBaudRateConfig->Enable(false);
		m_lblModeStatus->SetLabelText(L"无串口设备");
		return;
	}

	int selIdx = 0;
	for (std::size_t i = 0; i < curComPorts.size(); ++i) {
		const auto &port = curComPorts[i];
		auto name = wxString::Format(L"COM%d: %s", port.comPortNum, port.devDesc);
		mSelSerialPorts->AppendString(name);
		if (boost::icontains(name, L"Arduino")) {
			selIdx = static_cast<int>(i);
		}
	}
	mSelSerialPorts->SetSelection(selIdx);
}

void MainForm::ChangeWorkMode(WorkMode newMode) {
	if (curWorkMode == newMode) {
		return;
	}
	ClearWaveform();
	m_pnlDeviceConfig->Enable(newMode != WorkMode::Disable);
	LeaveWorkMode(curWorkMode);
	curWorkMode = newMode;
	EnterWorkMode(curWorkMode);
}

void MainForm::LeaveWorkMode(WorkMode workMode) {
	EnableWorkModeUserInterface(workMode, false);
	auto txt = m_lblModeStatus->GetLabelText();
	auto name = GetWorkModeName(workMode);
	if (txt == name) {
		m_lblModeStatus->SetLabelText(L"");
	}
	if (workMode == WorkMode::AudioWave && targetDevice) {
		targetDevice->LeaveAudioRmsMode();
	}
}

void MainForm::EnterWorkMode(WorkMode workMode) {
	EnableWorkModeUserInterface(workMode, true);
	ResetWorkModeUserInterface(workMode);
	m_lblModeStatus->SetLabelText(GetWorkModeName(workMode));
	EnableWorkMode4TartetDevice(workMode);
}

void MainForm::EnableWorkModeUserInterface(WorkMode workMode, bool state) {
	switch (workMode)
	{
	case WorkMode::Switch:
		m_switchON->Enable(state);
		m_switchOFF->Enable(state);
		break;
	case WorkMode::Stepless:
		m_slidrSetplessDiming->Enable(state);
		break;
	case WorkMode::Sawtooth:
		m_slidrSawInterval->Enable(state);
		break;
	case WorkMode::Triangle:
		m_slidrTrianInterval->Enable(state);
		break;
	case WorkMode::SinWave:
		m_slidrSinInterval->Enable(state);
		break;
	case WorkMode::AudioWave:
		break;
	default:
		break;
	}
}

void MainForm::ResetWorkModeUserInterface(WorkMode workMode) {
	switch (workMode)
	{
	case WorkMode::Switch:
		m_switchON->SetValue(true);
		m_switchOFF->SetValue(false);
		break;
	case WorkMode::Stepless:
	{
		auto min = m_slidrSetplessDiming->GetMin();
		auto max = m_slidrSetplessDiming->GetMax();
		m_slidrSetplessDiming->SetValue((min + max) / 2);
		break;
	}
	case WorkMode::Sawtooth:
	{
		auto min = m_slidrSawInterval->GetMin();
		auto max = m_slidrSawInterval->GetMax();
		m_slidrSawInterval->SetValue((min + max) / 2);
		break;
	}
	case WorkMode::Triangle:
	{
		auto min = m_slidrTrianInterval->GetMin();
		auto max = m_slidrTrianInterval->GetMax();
		m_slidrTrianInterval->SetValue((min + max) / 2);
		break;
	}
	case WorkMode::SinWave:
	{
		auto min = m_slidrSinInterval->GetMin();
		auto max = m_slidrSinInterval->GetMax();
		m_slidrSinInterval->SetValue((min + max) / 2);
		break;
	}
	case WorkMode::AudioWave:
	{
		break;
	}
	default:
		break;
	}
}

wxString MainForm::GetWorkModeName(WorkMode workMode) const {
	switch (workMode)
	{
	case WorkMode::Switch:
		return L"开关模式";
	case WorkMode::Stepless:
		return L"无级调光模式";
	case WorkMode::Sawtooth:
		return L"锯齿波模式";
	case WorkMode::Triangle:
		return L"三角波模式";
	case WorkMode::SinWave:
		return L"正弦波模式";
	case WorkMode::AudioWave:
		return L"动态跟随模式";
	default:
		break;
	}
	return {};
}

void MainForm::OnReportLedStatus(double time, double lighteness) {
	WaveformPostNewData(time, lighteness);
}

void MainForm::OnReceiveRMS(int tag, double time, double rms) {
	WaveformPostNewData(time, rms, tag);
}

bool MainForm::EnableWorkMode4TartetDevice(WorkMode workMode) {
	if (!targetDevice) {
		return false;
	}
	targetDevice->ResetReportTime();

	switch (workMode)
	{
	case WorkMode::Switch:
		targetDevice->LedSetFixedLightness(m_switchON->GetValue() ? 100.0 : 0.0);
		break;
	case WorkMode::Stepless:
		targetDevice->LedSetFixedLightness(m_slidrSetplessDiming->GetValue());
		break;
	case WorkMode::Sawtooth:
		targetDevice->LedSetSawtoothWave(m_slidrSawInterval->GetValue());
		break;
	case WorkMode::Triangle:
		targetDevice->LedSetTriangleWave(m_slidrTrianInterval->GetValue());
		break;
	case WorkMode::SinWave:
		targetDevice->LedSetSinWave(m_slidrSinInterval->GetValue());
		break;
	case WorkMode::AudioWave:
		targetDevice->LedSetAudioRmsMode(1.0);
		break;
	default:
		break;
	}
	
	targetDevice->StartReport();
	return true;
}